<template>
    <div i="upload" :class="[{ 'single': limit === 1, 'float': float }, listType]">
        <el-upload
            class="wrap"
            :class="{ 'avatar-uploader': listType === 'text', 'disabled': disabled || imageList.length >= limit }"
            ref="uploadForm"
            :disabled="disabled"
            :accept="accept"
            :multiple="multiple"
            :limit="limit"
            :auto-upload="autoUpload"
            :action="uploadApi"
            :data="uploadData"
            :list-type="listType"
            :show-file-list="showFileList"
            :file-list="defaultList"
            :on-preview="uploadPreview"
            :on-remove="uploadRemove"
            :on-success="uploadSuccess"
            :on-error="uploadError"
            :on-change="uploadChange"
            :before-upload="beforeUpload">
            <i v-if="listType === 'picture-card'" class="el-icon-plus avatar-uploader-icon" />
            <div v-else-if="listType === 'btn'">
                <el-button v-if="!disabled" size="small" type="primary">点击上传</el-button>
            </div>
            <div v-else>
                <img v-if="imageList.length" :src="imageList[imageList.length - 1].url" class="avatar">
                <div v-else class="el-icon-box">
                    <i class="el-icon-plus avatar-uploader-icon"></i>
                    <span class="el-icon-txt">点击上传</span>
                </div>
            </div>
        </el-upload>
        <div class="tip">
            <slot name="tip" />
        </div>

        <CommonDialog
            title="预览"
            :visible="previewDialog.visible"
            :rows="previewDialog.rows"
            :form="previewDialog.form"
            :labelWidth="0"
            @hideDialog="previewDialog.visible = false"
            @confirm="previewDialog.visible = false">
            <img slot="imgUrl" width="100%" :src="previewDialog.form.imgUrl" alt="">
        </CommonDialog>
    </div>
</template>
<script>
import util from '/@/util/util'
export default {
    name: 'upload',
    props: {
        disabled: {
            type: Boolean,
            default: false
        },
        accept: {
            type: String,
            default: 'image/*'
        },
        multiple: {
            type: Boolean,
            default: false
        },
        limit: {
            type: Number,
            default: null
        },
        listType: {
            type: String,
            default: 'text'
        },
        autoUpload: {
            type: Boolean,
            default: true
        },
        defaultList: {
            type: Array,
            default: () => []
        },
        maxSize: {
            type: Number,
            default: 2
        },
        float: {
            type: Boolean,
            default: false
        },
        type: {
            type: Number,
            default: 1
        }
    },
    data () {
        return {
            uploadApi: '',
            uploadData: {},
            imageList: this.defaultList,
            previewDialog: {
                visible: false,
                form: {
                    imgUrl: ''
                },
                rows: {
                    'imgUrl': {
                        slot: true
                    }
                }
            }
        }
    },
    computed: {
        showFileList () {
            switch (this.listType) {
                case 'text':
                    return false;
                default:
                    return true;
            }
        }
    },
    watch: {
        defaultList (newVal) {
            this.imageList = newVal;
        }
    },
    mounted () {
        this.init();
    },
    methods: {
        init () {
            this.uploadApi = util.uploadURL()
            this.uploadData = {
                type: this.type
            }
        },
        // 上传文件前
        beforeUpload (file) {
            return util.beforeUpload(this.$refs['uploadForm']);
        },
        // 上传文件成功
        uploadSuccess (res, file, fileList) {
            if (res.code === 0) {
                let { accessUrl } = res.data;
                this.$emit('success', accessUrl)
            } else {
                this.uploadError(res, file, fileList)
            }
        },
        // 上传文件失败
        uploadError (err, file, fileList) {
            this.$message.error(err.msg);
            this.$refs.uploadForm.uploadFiles = fileList.slice(0, fileList.length - 1);
            this.$emit('error', err, file, fileList)
        },
        // 改变图片
        uploadChange (file, fileList) {
            if (file.status === 'success') return;
            const isLimit = file.raw.size / 1024 / 1024 < this.maxSize;
            if (!isLimit) {
                this.$message.error(`图片大小不能超过 ${this.maxSize}MB`);
                return false;
            }
            this.$emit('change', file, fileList)
        },
        uploadPreview (file) {
            let suffix = file.url.substring(file.url.lastIndexOf('.') + 1, file.url.length).toLowerCase();
            let acceptFormats = ['png', 'jpg', 'jpeg', 'gif'];
            if (!acceptFormats.includes(suffix)) {
                window.open(file.url);
                return;
            };
            Object.assign(this.previewDialog, {
                visible: true,
                form: {
                    imgUrl: file.url
                }
            });
            this.$emit('preview', file)
        },
        uploadRemove (file, fileList) {
            this.$emit('remove', file, fileList)
        }
    }
}
</script>
<style lang="scss">
    [i="upload"] {
        &.float {
            max-width: 200px;
            .wrap {
                text-align: center;
            }
            .tip {
                text-align: center;
            }
        }
        &.btn {
            .el-upload-list {
                display: block;
            }
        }
        .el-upload-list {
            display: inline-flex;
            flex-wrap: wrap;
        }
        .disabled {
            .el-upload--btn,
            .el-upload--picture-card {
                display: none;
            }
        }
        .tip {
            color: #adb3b8;
            font-size: 12px;
            line-height: 1;
            word-break: keep-all;
            margin-top: 10px;
        }
    }
</style>
